﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Markup;

namespace Mesuro.Graphing.PropertiesControls {
	[TemplatePart( Name = "PART_Button", Type = typeof( ToggleButton ) )]
	public class ColorControl : Control {

		#region DP: Color
		public static readonly DependencyProperty ColorProperty = DependencyProperty.RegisterAttached( "Color", typeof( Color ), typeof( ColorControl ), new FrameworkPropertyMetadata( Colors.Black, FrameworkPropertyMetadataOptions.None, ColorChangedStatic ) );
		public Color Color {
			get { return (Color)GetValue( ColorProperty ); }
			set { SetValue( ColorProperty, value ); }
		}
		public static Color GetColor( DependencyObject element ) { return (Color)element.GetValue( ColorProperty ); }
		public static void SetColor( DependencyObject element, Color value ) { element.SetValue( ColorProperty, value ); }
		private static void ColorChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			ColorControl obj = sender as ColorControl;
			if (obj != null)
				obj.OnColorChanged( (Color)e.OldValue, (Color)e.NewValue );
		}
		#endregion

		#region DP: AlphaVariable
		public static readonly DependencyProperty AlphaVariableProperty = DependencyProperty.RegisterAttached( "AlphaVariable", typeof( bool ), typeof( ColorControl ), new FrameworkPropertyMetadata( true, FrameworkPropertyMetadataOptions.None, AlphaVariableChangedStatic ) );
		public bool AlphaVariable {
			get { return (bool)GetValue( AlphaVariableProperty ); }
			set { SetValue( AlphaVariableProperty, value ); }
		}
		public static bool GetAlphaVariable( DependencyObject element ) { return (bool)element.GetValue( AlphaVariableProperty ); }
		public static void SetAlphaVariable( DependencyObject element, bool value ) { element.SetValue( AlphaVariableProperty, value ); }
		private static void AlphaVariableChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			ColorControl obj = sender as ColorControl;
			if (obj != null)
				obj.OnAlphaVariableChanged( (bool)e.OldValue, (bool)e.NewValue );
		}
		#endregion

		#region DP: IsEditing
		public static readonly DependencyProperty IsEditingProperty = DependencyProperty.RegisterAttached( "IsEditing", typeof( bool ), typeof( ColorControl ), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.None, IsEditingChangedStatic ) );
		public bool IsEditing {
			get { return (bool)GetValue( IsEditingProperty ); }
			set { SetValue( IsEditingProperty, value ); }
		}
		public static bool GetIsEditing( DependencyObject element ) { return (bool)element.GetValue( IsEditingProperty ); }
		public static void SetIsEditing( DependencyObject element, bool value ) { element.SetValue( IsEditingProperty, value ); }
		public static void IsEditingChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			ColorControl obj = sender as ColorControl;
			if (obj != null)
				obj.OnIsEditingChanged( (bool)e.OldValue, (bool)e.NewValue );
		}
		#endregion

		#region DP: Editor
		public static readonly DependencyProperty EditorProperty = DependencyProperty.RegisterAttached( "Editor", typeof( ColorEditor ), typeof( ColorControl ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.None, EditorChangedStatic ) );
		public ColorEditor Editor {
			get { return (ColorEditor)GetValue( EditorProperty ); }
			set { SetValue( EditorProperty, value ); }
		}
		public static ColorEditor GetEditor( System.Windows.DependencyObject element ) { return (ColorEditor)element.GetValue( EditorProperty ); }
		public static void SetEditor( System.Windows.DependencyObject element, ColorEditor value ) { element.SetValue( EditorProperty, value ); }
		private static void EditorChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			ColorControl cc = sender as ColorControl;
			if (cc != null)
				cc.OnEditorChanged( (ColorEditor)e.OldValue, (ColorEditor)e.NewValue );
		}
		#endregion

		#region DP: ContentTemplate
		public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.RegisterAttached( "ContentTemplate", typeof( DataTemplate ), typeof( ColorControl ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.None, ContentTemplateChangedStatic ) );
		public DataTemplate ContentTemplate {
			get { return (DataTemplate)GetValue( ContentTemplateProperty ); }
			set { SetValue( ContentTemplateProperty, value ); }
		}
		public static DataTemplate GetContentTemplate( DependencyObject element ) { return (DataTemplate)element.GetValue( ContentTemplateProperty ); }
		public static void SetContentTemplate( DependencyObject element, DataTemplate value ) { element.SetValue( ContentTemplateProperty, value ); }
		private static void ContentTemplateChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			ColorControl obj = sender as ColorControl;
			if (obj != null)
				obj.OnContentTemplateChanged( (DataTemplate)e.OldValue, (DataTemplate)e.NewValue );
		}
		#endregion

		private readonly Popup popup = new Popup() { StaysOpen = false };
		private ToggleButton button;

		static ColorControl() {
			HorizontalContentAlignmentProperty.OverrideMetadata( typeof( ColorControl ), new FrameworkPropertyMetadata( HorizontalAlignment.Stretch ) );
			VerticalContentAlignmentProperty.OverrideMetadata( typeof( ColorControl ), new FrameworkPropertyMetadata( VerticalAlignment.Stretch ) );
			DefaultStyleKeyProperty.OverrideMetadata( typeof( ColorControl ), new FrameworkPropertyMetadata( typeof( ColorControl ) ) );
		}
		public ColorControl() {
			popup.PlacementTarget = this;
			popup.SetBinding( Popup.WidthProperty, new Binding( ActualWidthProperty.Name ) { Source = this, Mode = BindingMode.OneWay } );
			popup.SetBinding( Popup.ChildProperty, new Binding( EditorProperty.Name ) { Source = this, Mode = BindingMode.OneWay } );
			popup.SetBinding( Popup.IsOpenProperty, new Binding( IsEditingProperty.Name ) { Source = this, Mode = BindingMode.TwoWay } );
			Editor = new ColorEditor();
		}

		protected virtual void OnColorChanged( Color oldValue, Color newValue ) { }
		protected virtual void OnAlphaVariableChanged( bool oldValue, bool newValue ) { }
		protected virtual void OnIsEditingChanged( bool oldValue, bool newValue ) {
		}
		BindingExpressionBase exp;
		protected virtual void OnEditorChanged( ColorEditor oldValue, ColorEditor newValue ) {
			exp = Editor.SetBinding( ColorEditor.ColorProperty, new Binding( ColorProperty.Name ) { Source = this, Mode = BindingMode.TwoWay } );
			Editor.SetBinding( ColorEditor.AlphaVariableProperty, new Binding( AlphaVariableProperty.Name ) { Source = this, Mode = BindingMode.TwoWay } );
		}
		protected virtual void OnContentTemplateChanged( DataTemplate oldValue, DataTemplate newValue ) { }

		public override void OnApplyTemplate() {
			base.OnApplyTemplate();
			button = (ToggleButton)GetTemplateChild( "PART_Button" );
			if (button != null) {
				button.SetBinding( ToggleButton.IsCheckedProperty, new Binding( IsEditingProperty.Name ) { Source = this, Mode = BindingMode.TwoWay } );
			}
		}
	}
}
